Skip to content

Conversation

6by9
Copy link
Contributor

@6by9 6by9 commented Sep 11, 2025

All the matrix entries for the YUV to RGB conversion matrices were being filled with the same coefficients.
Compute the values for the BT601, BT709, and BT2020 matrices in both full and limited range, and program those into the hardware.

@cillian64 Hopefully this resolves your issue in getting no change between the settings.

I believe the matrices are correct, but don't believe we have any tests to confirm (we probably ought to, and it shouldn't be too difficult if extending John's drmu 10bittest which already captures the output of the writeback connector).

* put it before.
*/
struct vc6_d0_csc_coeff_entry {
u32 csc[3][4];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we likely to get any value from the third and fourth elements in the array, given that they're all fixed and 2 of the 6 aren't used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, it's only the actual matrix that changes, and that is contained within the first 2 u32's of each row. Leaving the clamping and flag for offsets before multiply as fixed would work.

@cillian64
Copy link
Contributor

Thanks, this seems to mostly work (although I can't tell if the colour matrices are actually the right ones, just that they are different now).

However, with full-range, BT2020 and BT601 look identical, which I'm pretty sure is wrong.

@6by9
Copy link
Contributor Author

6by9 commented Sep 15, 2025

However, with full-range, BT2020 and BT601 look identical, which I'm pretty sure is wrong.

I'd taken the basic numbers from https://gist.github.com/yohhoy/dafa5a47dade85d8b40625261af3776a and then done the relevant shifts to make up our table.
For BT601 I worked out:

1 | 1.402 | 0
1 | -0.714136286201022 | -0.344136286201022
1 | 0 | 1.772

Multiply by 8192 as 12bit fixed point
8192 | 0 | 11485
8192 | -2819 | -5850
8192 | 14516 | 0

And convert to hex
2000 | 0 | 2cdd
2000 | f4fd| e926
2000 | 38b4 | 0

For BT2020:

1 | 1.4746 | 0
1 | -0.5713 | -0.1645
1 | 0 | 1.8814

Multiply by 8192 as 12bit fixed point
8192 | 0 | 12080
8192 | -1348 | -4681
8192 | 15201 | 0

And convert to hex
2000 | 0 | 2f30
2000 | fabc | edb7
2000 | 3c34 | 0

So assuming I have the right source coefficients, they don't appear that radically different.

@cillian64
Copy link
Contributor

Comparing to a Pi 4, they do look noticeably different there. And also with EGL_EXT_image_dma_buf_import's colorspace and range options. I think it's your BT2020 which is wrong (it shows greens noticeably darker than BT601 on pi4 and EGL)

@6by9
Copy link
Contributor Author

6by9 commented Sep 15, 2025

Converting backwards from the GEN4/5 register values I get

1 | 1.47265 | 0
1 | -0.5742 | -0.1641
1 | 0 | 1.8828

which is close enough to

1 | 1.4746 | 0
1 | -0.5713 | -0.1645
1 | 0 | 1.8814

to put down to rounding due to 2p8 fixed point representation.

More poking required.

@6by9
Copy link
Contributor Author

6by9 commented Sep 15, 2025

Wood from the trees - it's 2020 limited range that is still the same as 601 limited range.

I could have sworn I'd found a doc with that one in, but obviously not.

All the matrix entries for the YUV to RGB conversion matrices were
being filled with the same coefficients.
Compute the values for the BT601, BT709, and BT2020 matrices in
both full and limited range, and program those into the hardware.

Signed-off-by: Dave Stevenson <[email protected]>
@6by9
Copy link
Contributor Author

6by9 commented Sep 15, 2025

Branch updated with new coefficients for BT2020 limited range.

Having captured frames via writeback using 10bittest -e <colourencoding> -r <range> -y -w, the diff between the output on 2711 vs 2712D0 is in the LSB.

@cillian64
Copy link
Contributor

Thanks! Confirmed that with my test all 6 matrices now look different.

@pelwell pelwell merged commit 8d376f1 into raspberrypi:rpi-6.12.y Sep 16, 2025
12 checks passed
popcornmix added a commit to raspberrypi/firmware that referenced this pull request Sep 22, 2025
kernel: dtoverlays: adjust inbound windows for MIP1 on Pi 5 with 32-bit PCIe DMA
See: raspberrypi/linux#7049

kernel: drm/vc4: hvs: Populate YUV to RGB matrices for GEN_6D
See: raspberrypi/linux#7043

kernel: DRM command line parser fix
See: raspberrypi/linux#7051

kernel: Overlays: rpi-power-hat i2c_arm enable
See: raspberrypi/linux#7055

kernel: configs: Add CONFIG_W1_SLAVE_DS2430=m
See: raspberrypi/linux#7056

kernel: media: i2c: imx219: Scale the pixel rate for analog binning
See: raspberrypi/linux#7045
popcornmix added a commit to raspberrypi/rpi-firmware that referenced this pull request Sep 23, 2025
kernel: dtoverlays: adjust inbound windows for MIP1 on Pi 5 with 32-bit PCIe DMA
See: raspberrypi/linux#7049

kernel: drm/vc4: hvs: Populate YUV to RGB matrices for GEN_6D
See: raspberrypi/linux#7043

kernel: DRM command line parser fix
See: raspberrypi/linux#7051

kernel: Overlays: rpi-power-hat i2c_arm enable
See: raspberrypi/linux#7055

kernel: configs: Add CONFIG_W1_SLAVE_DS2430=m
See: raspberrypi/linux#7056

kernel: media: i2c: imx219: Scale the pixel rate for analog binning
See: raspberrypi/linux#7045
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants